<template>
  <!-- 签名横屏 -->
  <view class="signa">
    <view class="box">
      <canvas
        class="canvas"
        disable-scroll="true"
        :style="{ width: width + 'px', height: height + 'px' }"
        canvas-id="designature"
        @touchstart="starts"
        @touchmove="moves"
        @touchend="end"
      ></canvas>
      <view class="bottomBox u-flex">
        <view class="tip">请你在此手动签写自己的签章，签写操作完毕点击保存按钮</view>
        <view class="btn" style="margin-top: 18vw" @click="cancel">取消</view>
        <view class="btn" style="margin-top: 8vw" @click="clear">清除</view>
        <view class="btn blue" @click="save" style="margin-top: 8vw">保存</view>
      </view>
      <canvas
        class="designature_rotate"
        :style="{ width: rotateW, height: rotateH }"
        canvas-id="designature_rotate"
      ></canvas>
    </view>
  </view>
</template>

<script>
export default {
  props: {
    lineWidth: {
      type: [Number, String],
      default: 5,
    },
    lineColor: {
      type: String,
      default: "black",
    },
    // 图片格式【url|base64】
    imageType: {
      type: String,
      default: "url",
    },
  },
  data() {
    return {
      resultUrl: "",
      canvasContext: null,
      line: [],
      rotateW: 2000,
      rotateH: 2000,
      width: 0,
      height: 0,
      radius: 0,
    };
  },
  created() {
    uni.getSystemInfo({
      success: (res) => {
        this.width = res.windowWidth - 30;
        this.height = res.windowHeight - 180;
      },
    });
    this.canvasContext = uni.createCanvasContext("designature", this);
  },
  methods: {
    cancel() {
      //   uni.navigateBack();
      this.clear();
      this.$nextTick(() => {
        this.$emit("cancel");
      });
    },
    end(e) {},
    distance(a, b) {
      let x = b.x - a.x;
      let y = b.y - a.y;
      return Math.sqrt(x * x + y * y);
    },
    starts(e) {
      this.line.push({
        points: [
          {
            time: new Date().getTime(),
            x: e.touches[0].x,
            y: e.touches[0].y,
            dis: 0,
          },
        ],
      });
      let currentPoint = {
        x: e.touches[0].x,
        y: e.touches[0].y,
      };
      this.currentPoint = currentPoint;
      this.drawer(this.line[this.line.length - 1]);
    },
    moves(e) {
      let point = {
        x: e.touches[0].x,
        y: e.touches[0].y,
      };
      this.lastPoint = this.currentPoint;
      this.currentPoint = point;
      this.line[this.line.length - 1].points.push({
        time: new Date().getTime(),
        x: e.touches[0].x,
        y: e.touches[0].y,
        dis: this.distance(this.currentPoint, this.lastPoint),
      });
      this.drawer(this.line[this.line.length - 1]);
    },
    drawer(item) {
      let x1,
        x2,
        y1,
        y2,
        cx,
        cy,
        t = 0.5,
        x,
        y;
      if (item.points.length > 2) {
        let lines = item.points[item.points.length - 3];
        let line = item.points[item.points.length - 2];
        let end = item.points[item.points.length - 1];
        x = line.x;
        y = line.y;
        x1 = lines.x;
        y1 = lines.y;
        x2 = end.x;
        y2 = end.y;
        let canvasContext = this.canvasContext;
        cx = (x - Math.pow(1 - t, 2) * x1 - Math.pow(t, 2) * x2) / (2 * t * (1 - t));
        cy = (y - Math.pow(1 - t, 2) * y1 - Math.pow(t, 2) * y2) / (2 * t * (1 - t));
        canvasContext.setLineCap("round");
        canvasContext.beginPath();
        canvasContext.setStrokeStyle(this.lineColor);
        canvasContext.setLineWidth(this.lineWidth);
        canvasContext.moveTo(x1, y1);
        canvasContext.quadraticCurveTo(cx, cy, x2, y2);

        canvasContext.stroke();
        canvasContext.draw(true);
      }
    },
    clear() {
      this.rotateCanvasContext.clearRect(0, 0, 1000, 1000);
      this.rotateCanvasContext.draw();
      this.clearRotateContext();
    },
    clearRotateContext() {
      this.canvasContext.clearRect(0, 0, 1000, 1000);
      this.canvasContext.draw();
    },
    save() {
      const _this = this;
      uni.canvasToTempFilePath(
        {
          canvasId: "designature",
          fileType: "png",
          quality: 1, //图片质量
          success(res) {
            wx.getImageInfo({
              // 获取图片的信息
              src: res.tempFilePath,
              success: (res1) => {
                _this.rotateCanvasContext = uni.createCanvasContext(
                  "designature_rotate",
                  _this
                );
                let rate = res1.height / res1.width;
                let width = 200 / rate;
                let height = 300;
                _this.rotateCanvasContext.translate(height / 2, width / 2);
                _this.rotateCanvasContext.rotate((270 * Math.PI) / 180);
                _this.rotateCanvasContext.drawImage(
                  res.tempFilePath,
                  -width / 2,
                  -height / 2,
                  width,
                  height
                );
                _this.rotateCanvasContext.draw(false, () => {
                  uni.canvasToTempFilePath(
                    {
                      canvasId: "designature_rotate",
                      fileType: "png",
                      quality: 1, //图片质量
                      success: function (res) {
                        _this.clear();
                        _this.setImageUrl(res);
                      },
                      fail(e) {
                        console.log(e);
                      },
                    },
                    _this
                  );
                });
              },
            });
          },
        },
        this
      );
    },
    setImageUrl(e) {
      const _this = this;
      this.$nextTick(() => {
        if (this.imageType === "url") {
          this.$emit("getImg", e.tempFilePath);
        } else if (this.imageType === "base64") {
          wx.getFileSystemManager().readFile({
            filePath: e.tempFilePath, //要读取的文件的路径 (本地路径)
            encoding: "base64", //指定读取文件的字符编码，如果不传 encoding，则以 ArrayBuffer 格式读取文件的二进制内容
            success(res) {
              _this.$emit("getImg", `data:image/png;base64,${res.data}`);
            },
          });
        }
      });
    },
    getImageInfo() {
      const t = this;
      // 将之前在绘图上下文中的描述（路径、变形、样式）画到 canvas 中
      uni.canvasToTempFilePath(
        {
          // 把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功。
          canvasId: "designature_rotate",
          fileType: "png",
          quality: 1, //图片质量
          success: function (res) {
            // 调用uni.uploadFile上传图片即可
            t.clear();
            t.$nextTick(() => {
              if (_this.imageType === "url") {
                _this.$emit("getImg", res.tempFilePath);
              } else if (_this.imageType === "base64") {
                wx.getFileSystemManager().readFile({
                  filePath: res.tempFilePath, //要读取的文件的路径 (本地路径)
                  encoding: "base64", //指定读取文件的字符编码，如果不传 encoding，则以 ArrayBuffer 格式读取文件的二进制内容
                  success(res) {
                    _this.$emit("getImg", `data:image/png;base64,${res.data}`);
                  },
                });
              }
            });
          },
          fail(e) {
            console.log(e);
          },
        },
        this
      );
    },
  },
};
</script>

<style scoped lang="scss">
.signa {
  position: relative;
  overflow: hidden;
  padding: 30rpx;
  .box {
    position: relative;
    background-color: #fff;
    border-radius: 20rpx;
    box-shadow: 0 6rpx 42rpx rgba(0, 0, 0, 0.05);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }
  .canvas {
    background-color: #e6e6e6;
    position: relative;
    z-index: 9999;
  }
  .designature_rotate {
    background-color: #e6e6e6;
    position: absolute;
  }
  .bottomBox {
    flex-direction: column;
    justify-content: center;
    width: 100px;
    height: 80vw;
    padding: 10px;
    position: fixed;
    left: 50%;
    bottom: -40vw;
    transform: rotate(90deg);
    margin-left: -50px;
    margin-bottom: 72px;
    .tip {
      font-size: 11px;
      color: #ff6f77;
    }
    .btn {
      width: 100%;
      height: 37px;
      background: #f5f5f5;
      border-radius: 19px;
      margin-top: 7px;
      text-align: center;
      line-height: 37px;
      color: #333333;
      font-size: 13px;
      &.blue {
        background: #284cf4;
        color: #fff;
      }
    }
  }
}
</style>
